package com.android.lovely.ui.widget

import android.annotation.SuppressLint
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewTreeObserver
import android.view.animation.DecelerateInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet

/**
 * 字体大小选择器
 * 实现圆形滑块在线上移动并停靠在指定位置的功能
 */
class FontSizeSelector(
    private val parent: ConstraintLayout,
    private val round: View,
    private val line: View,
    private val stopPoints: List<View>
) {
    companion object {
        private const val ANIMATION_DURATION: Long = 200
        private const val TAG = "FontSizeSelector"
    }

    // 当前选中的位置索引（0-4）
    private var currentIndex: Int = 0

    // 选择变化监听器
    private var onSizeSelectedListener: ((index: Int) -> Unit)? = null

    init {
        // 确保所有视图都有ID
        ensureViewsHaveIds()

        // 等待布局完成后初始化
        waitForLayout()
    }

    /**
     * 等待布局完成
     */
    private fun waitForLayout() {
        line.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                if (line.width > 0 && stopPoints.all { it.width > 0 }) {
                    // 移除监听器
                    line.viewTreeObserver.removeOnGlobalLayoutListener(this)

                    // 设置触摸监听器
                    setupTouchListener()

                    // 设置初始位置
                    moveToStopPoint(currentIndex, false)

                    Log.d(TAG, "Layout ready")
                }
            }
        })
    }

    /**
     * 确保所有视图都有ID
     */
    private fun ensureViewsHaveIds() {
        if (round.id == View.NO_ID) {
            round.id = View.generateViewId()
        }

        if (line.id == View.NO_ID) {
            line.id = View.generateViewId()
        }

        stopPoints.forEach { point ->
            if (point.id == View.NO_ID) {
                point.id = View.generateViewId()
            }
        }

        ensureAllChildrenHaveIds(parent)
    }

    /**
     * 确保所有子视图都有ID
     */
    private fun ensureAllChildrenHaveIds(layout: ConstraintLayout) {
        for (i in 0 until layout.childCount) {
            val child = layout.getChildAt(i)
            if (child.id == View.NO_ID) {
                child.id = View.generateViewId()
            }

            if (child is ConstraintLayout) {
                ensureAllChildrenHaveIds(child)
            }
        }
    }

    /**
     * 设置触摸监听器
     */
    @SuppressLint("ClickableViewAccessibility")
    private fun setupTouchListener() {
        // 创建一个透明触摸层覆盖在line上
        val touchArea = View(parent.context).apply {
            id = View.generateViewId()
            setBackgroundColor(0x00000000) // 完全透明
        }

        // 添加触摸层到布局中
        val params = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_CONSTRAINT,
            line.height * 10 // 触摸区域高度为line高度的3倍
        )
        parent.addView(touchArea, params)

        // 设置触摸层的约束
        val set = ConstraintSet()
        set.clone(parent)

        // 水平约束与line一致
        set.connect(touchArea.id, ConstraintSet.START, line.id, ConstraintSet.START)
        set.connect(touchArea.id, ConstraintSet.END, line.id, ConstraintSet.END)

        // 垂直居中于line
        set.connect(touchArea.id, ConstraintSet.TOP, line.id, ConstraintSet.TOP, -line.height)
        set.connect(touchArea.id, ConstraintSet.BOTTOM, line.id, ConstraintSet.BOTTOM, line.height)

        set.applyTo(parent)

        // 设置触摸监听
        touchArea.setOnTouchListener { _, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    // 按下时不做任何改变
                    return@setOnTouchListener true
                }
                MotionEvent.ACTION_MOVE -> {
                    // 移动时不做任何改变 - 滑块不跟随手指移动
                    return@setOnTouchListener true
                }
                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    // 触摸结束时，找到最近的停靠点
                    val touchX = getRelativeTouchPosition(touchArea, event)
                    val nearestIndex = findNearestStopPoint(touchX)
                    moveToStopPoint(nearestIndex, true)
                    return@setOnTouchListener true
                }
            }
            false
        }

        // 同时为line也设置触摸监听，以增加鲁棒性
        line.setOnTouchListener { _, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
                    // 不做任何改变 - 滑块不跟随手指移动
                    return@setOnTouchListener true
                }
                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    val nearestIndex = findNearestStopPoint(event.x)
                    moveToStopPoint(nearestIndex, true)
                    return@setOnTouchListener true
                }
            }
            false
        }
    }

    /**
     * 获取触摸点在line上的相对位置
     */
    private fun getRelativeTouchPosition(touchView: View, event: MotionEvent): Float {
        // 计算触摸点相对于触摸区域的位置
        val touchX = event.x

        // 计算触摸区域相对于line的位置偏移
        val touchViewLoc = IntArray(2)
        touchView.getLocationOnScreen(touchViewLoc)

        val lineLoc = IntArray(2)
        line.getLocationOnScreen(lineLoc)

        // 计算触摸点相对于line的位置
        val offsetX = touchViewLoc[0] - lineLoc[0]
        val relativeX = touchX - offsetX

        return relativeX
    }

    /**
     * 查找最近的停靠点
     */
    private fun findNearestStopPoint(touchX: Float): Int {
        var minDistance = Float.MAX_VALUE
        var nearestIndex = 0

        stopPoints.forEachIndexed { index, point ->
            val pointCenter = point.x + point.width / 2
            val distance = Math.abs(pointCenter - touchX)

            if (distance < minDistance) {
                minDistance = distance
                nearestIndex = index
            }
        }

        return nearestIndex
    }

    /**
     * 移动到指定停靠点
     */
    private fun moveToStopPoint(index: Int, animate: Boolean) {
        if (index < 0 || index >= stopPoints.size) return

        val targetView = stopPoints[index]

        try {
            // 使用ConstraintSet进行约束
            val constraintSet = ConstraintSet()
            constraintSet.clone(parent)

            // 清除之前的所有水平约束
            constraintSet.clear(round.id, ConstraintSet.LEFT)
            constraintSet.clear(round.id, ConstraintSet.RIGHT)
            constraintSet.clear(round.id, ConstraintSet.START)
            constraintSet.clear(round.id, ConstraintSet.END)

            // 设置水平居中对齐 - 使用START和END约束
            constraintSet.connect(
                round.id,
                ConstraintSet.START,
                targetView.id,
                ConstraintSet.START
            )

            constraintSet.connect(
                round.id,
                ConstraintSet.END,
                targetView.id,
                ConstraintSet.END
            )

            // 垂直居中于line
            constraintSet.connect(round.id, ConstraintSet.TOP, line.id, ConstraintSet.TOP)
            constraintSet.connect(round.id, ConstraintSet.BOTTOM, line.id, ConstraintSet.BOTTOM)

            // 应用约束 - 如果需要动画，则使用过渡动画
            if (animate) {
                // 创建过渡动画
                val transition = android.transition.ChangeBounds()
                transition.duration = ANIMATION_DURATION
                transition.interpolator = DecelerateInterpolator()

                // 应用过渡动画
                android.transition.TransitionManager.beginDelayedTransition(parent, transition)
            }

            // 应用约束
            constraintSet.applyTo(parent)

            // 记录日志 - 用于调试
            Log.d(TAG, "Moved to stop point: $index")

            // 更新当前索引并通知监听器
            if (currentIndex != index) {
                currentIndex = index
                onSizeSelectedListener?.invoke(currentIndex)
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to move to stop point", e)
        }
    }

    /**
     * 设置选择监听器
     */
    fun setOnSizeSelectedListener(listener: (index: Int) -> Unit) {
        onSizeSelectedListener = listener
    }

    /**
     * 设置当前选中的位置
     */
    fun setSelectedPosition(index: Int) {
        if (index in 0 until stopPoints.size) {
            moveToStopPoint(index, true)
        }
    }

    /**
     * 获取当前选中的位置索引
     */
    fun getCurrentIndex(): Int = currentIndex
}